#include "http.h"

char *STA_REQUEST = "GET " REQ_PATH " HTTP/1.0\r\n"
    "Host: "REQ_SERVER":"REQ_PORT"\r\n"
    "User-Agent: esp-idf/1.0 esp32\r\n"
    "\r\n";

int http_request(http_params params)
{
    const struct addrinfo hints = {
        .ai_family = AF_INET,
        .ai_socktype = SOCK_STREAM,
    };

    struct addrinfo *res;
    struct in_addr *addr;
    int s, r;
    char recv_buf[64];

    ESP_LOGI("HTTP", "HTTP REQ");

    int err = getaddrinfo(params.server, params.port, &hints, &res);

    if(err != 0 || res == NULL)
    {
        ESP_LOGE("HTTP", "DNS lookup failed err=%d res=%p", err, res);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        return 0;
    }

    addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
    ESP_LOGI("HTTP", "DNS lookup succeeded. IP=%s", inet_ntoa(*addr));

    s = socket(res->ai_family, res->ai_socktype, 0);
    if(s < 0)
    {
        ESP_LOGE("HTTP", "... Failed to allocate socket.");
        freeaddrinfo(res);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        return 0;
    }
    ESP_LOGI("HTTP", "... allocated socket");

    if(connect(s, res->ai_addr, res->ai_addrlen) != 0)
    {
        ESP_LOGE("HTTP", "... socket connect failed errno=%d", errno);
        close(s);
        freeaddrinfo(res);
        vTaskDelay(4000 / portTICK_PERIOD_MS);
        return 0;
    }

    ESP_LOGI("HTTP", "... connected");
    freeaddrinfo(res);

    if (write(s, params.request, strlen(params.request)) < 0)
    {
        ESP_LOGE("HTTP", "... socket send failed");
        close(s);
        vTaskDelay(4000 / portTICK_PERIOD_MS);
        return 0;
    }
    ESP_LOGI("HTTP", "... socket send success");

    struct timeval receiving_timeout;
    receiving_timeout.tv_sec = 5;
    receiving_timeout.tv_usec = 0;
    if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &receiving_timeout, sizeof(receiving_timeout)) < 0)
    {
        ESP_LOGE("HTTP", "... failed to set socket receiving timeout");
        close(s);
        vTaskDelay(4000 / portTICK_PERIOD_MS);
        return 0;
    }
    ESP_LOGI("HTTP", "... set socket receiving timeout success");

    int bytes_received = 0;
    bool start = false;
    bzero(params.buffer, params.len);

    do {
        bzero(recv_buf, sizeof(recv_buf));
        r = read(s, recv_buf, sizeof(recv_buf)-1);
        for(int i = 0; i < r; i++)
        {
            putchar(recv_buf[i]);
            if (recv_buf[i] == '{')
            {
                start = true;
            }
            if (start == true)
            {
                params.buffer[bytes_received] = recv_buf[i];
                bytes_received++;
            }
        }
    }
    while(r > 0);

    ESP_LOGI("HTTP", "... done reading from socket. Last read return=%d errno=%d.", r, errno);
    close(s);

    return bytes_received;
}
